<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>工业轴承振动监测系统</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.4.2/echarts.min.js"></script>
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .container {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 20px;
        }
        .bearing-panel {
            background-color: white;
            border-radius: 8px;
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
            padding: 15px;
            margin-bottom: 20px;
        }
        .bearing-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
            padding-bottom: 10px;
            border-bottom: 1px solid #eee;
        }
        .bearing-title {
            font-size: 18px;
            font-weight: bold;
        }
        .alert-status {
            padding: 5px 10px;
            border-radius: 4px;
            font-weight: bold;
        }
        .alert-normal {
            background-color: #d4edda;
            color: #155724;
        }
        .alert-warning {
            background-color: #fff3cd;
            color: #856404;
        }
        .alert-danger {
            background-color: #f8d7da;
            color: #721c24;
        }
        .chart-container {
            height: 300px;
            margin-bottom: 20px;
        }
        .audio-features {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 10px;
            margin-top: 15px;
        }
        .feature-box {
            background-color: #f8f9fa;
            padding: 8px;
            border-radius: 4px;
            font-size: 14px;
        }
        .feature-name {
            font-weight: bold;
            margin-bottom: 5px;
        }
        .feature-value {
            color: #6c757d;
        }
        .probability-bar {
            height: 20px;
            background-color: #e9ecef;
            border-radius: 4px;
            margin-top: 5px;
            overflow: hidden;
        }
        .probability-fill {
            height: 100%;
            background-color: #28a745;
            width: 0%;
            transition: width 0.3s ease, background-color 0.3s ease;
        }
        .probability-fill.warning {
            background-color: #ffc107;
        }
        .probability-fill.danger {
            background-color: #dc3545;
        }
        h1 {
            text-align: center;
            color: #333;
            margin-bottom: 30px;
        }
        @media (max-width: 768px) {
            .container {
                grid-template-columns: 1fr;
            }
        }
    </style>
</head>
<body>
    <h1>🏭 工业轴承振动监测系统</h1>
    <div class="container">
        {% for bearing in bearings %}
        <div class="bearing-panel" id="bearing-{{ bearing.id|add:1 }}">
            <div class="bearing-header">
                <div class="bearing-title">轴承 #{{ bearing.id|add:1 }}</div>
                <div class="alert-status alert-normal" id="bearing-{{ bearing.id|add:1 }}-status">正常</div>
            </div>

            <div class="chart-container" id="bearing-{{ bearing.id|add:1 }}-acceleration"></div>
            <div class="chart-container" id="bearing-{{ bearing.id|add:1 }}-velocity"></div>
            <div class="chart-container" id="bearing-{{ bearing.id|add:1 }}-temperature"></div>

            {% if bearing.audio_features %}
            <div class="chart-container" id="bearing-{{ bearing.id|add:1 }}-audio"></div>
            <div class="audio-features" id="bearing-{{ bearing.id|add:1 }}-features"></div>
            {% endif %}

            <div style="margin-top: 15px;">
                <div>故障概率: <span id="bearing-{{ bearing.id|add:1 }}-probability">0%</span></div>
                <div class="probability-bar">
                    <div class="probability-fill" id="bearing-{{ bearing.id|add:1 }}-probability-bar"></div>
                </div>
            </div>
        </div>
        {% endfor %}
    </div>

    <script>
        // 初始化所有图表
        const charts = {};

        // 从Django模板获取数据
        const backendData = {
            bearings: [
                {% for bearing in bearings %}
                {
                    id: {{ bearing.id }},
                    displayId: {{ bearing.id|add:1 }},
                    acceleration: {
                        x: {{ bearing.acceleration.x|default:0 }},
                        y: {{ bearing.acceleration.y|default:0 }},
                        z: {{ bearing.acceleration.z|default:0 }}
                    },
                    velocity: {
                        x: {{ bearing.velocity.x|default:0 }},
                        y: {{ bearing.velocity.y|default:0 }},
                        z: {{ bearing.velocity.z|default:0 }}
                    },
                    temperature: {{ bearing.temperature|default:0 }},
                    audioFeatures: {
                        {% if bearing.audio_features %}
                            {% for key, value in bearing.audio_features.items %}
                            "{{ key }}": {{ value|default:0 }}{% if not forloop.last %},{% endif %}
                            {% endfor %}
                        {% endif %}
                    },
                    probability: {{ bearing.prediction.abnormal_probability|default:0 }},
                    chartData: [
                        {% for data in bearing.chart_data %}
                        {
                            timestamp: "{{ data.timestamp|date:'H:i:s' }}",
                            acceleration: {
                                x: {{ data.x_acc_rms|default:0 }},
                                y: {{ data.y_acc_rms|default:0 }},
                                z: {{ data.z_acc_rms|default:0 }}
                            },
                            velocity: {
                                x: {{ data.x_v_rms|default:0 }},
                                y: {{ data.y_v_rms|default:0 }},
                                z: {{ data.z_v_rms|default:0 }}
                            },
                            temperature: {{ data.temperature|default:0 }},
                            audioFeatures: {
                                {% if data.audio_data and data.audio_data.extracted_features %}
                                    {% for key, value in data.audio_data.extracted_features.items %}
                                    "{{ key }}": {{ value|default:0 }}{% if not forloop.last %},{% endif %}
                                    {% endfor %}
                                {% endif %}
                            }
                        }{% if not forloop.last %},{% endif %}
                        {% endfor %}
                    ]
                }{% if not forloop.last %},{% endif %}
                {% endfor %}
            ]
        };

        // 初始化单个轴承的图表
        function initBearingCharts(bearing) {
            const chartData = bearing.chartData || [];
            const timestamps = chartData.map(d => d.timestamp);
            const displayId = bearing.displayId;

            // 1. 加速度图表
            charts[`acceleration-${displayId}`] = echarts.init(document.getElementById(`bearing-${displayId}-acceleration`));
            charts[`acceleration-${displayId}`].setOption({
                title: { text: '三轴加速度 (m/s²)', left: 'center' },
                tooltip: { trigger: 'axis' },
                legend: {
                    data: ['X轴', 'Y轴', 'Z轴'],
                    bottom: 0
                },
                grid: { top: '15%', bottom: '20%' },
                xAxis: {
                    type: 'category',
                    data: timestamps,
                    axisLabel: { rotate: 45 }
                },
                yAxis: { type: 'value', name: 'm/s²' },
                series: [
                    { name: 'X轴', type: 'line', showSymbol: false, data: chartData.map(d => d.acceleration.x) },
                    { name: 'Y轴', type: 'line', showSymbol: false, data: chartData.map(d => d.acceleration.y) },
                    { name: 'Z轴', type: 'line', showSymbol: false, data: chartData.map(d => d.acceleration.z) }
                ]
            });

            // 2. 速度图表
            charts[`velocity-${displayId}`] = echarts.init(document.getElementById(`bearing-${displayId}-velocity`));
            charts[`velocity-${displayId}`].setOption({
                title: { text: '三轴速度 (mm/s)', left: 'center' },
                tooltip: { trigger: 'axis' },
                legend: {
                    data: ['X轴', 'Y轴', 'Z轴'],
                    bottom: 0
                },
                grid: { top: '15%', bottom: '20%' },
                xAxis: {
                    type: 'category',
                    data: timestamps,
                    axisLabel: { rotate: 45 }
                },
                yAxis: { type: 'value', name: 'mm/s' },
                series: [
                    { name: 'X轴', type: 'line', showSymbol: false, data: chartData.map(d => d.velocity.x) },
                    { name: 'Y轴', type: 'line', showSymbol: false, data: chartData.map(d => d.velocity.y) },
                    { name: 'Z轴', type: 'line', showSymbol: false, data: chartData.map(d => d.velocity.z) }
                ]
            });

            // 3. 温度图表
            charts[`temperature-${displayId}`] = echarts.init(document.getElementById(`bearing-${displayId}-temperature`));
            charts[`temperature-${displayId}`].setOption({
                title: { text: '温度 (°C)', left: 'center' },
                tooltip: { trigger: 'axis' },
                grid: { top: '15%', bottom: '15%' },
                xAxis: {
                    type: 'category',
                    data: timestamps,
                    axisLabel: { rotate: 45 }
                },
                yAxis: { type: 'value', name: '°C' },
                series: [
                    {
                        name: '温度',
                        type: 'line',
                        showSymbol: false,
                        areaStyle: { opacity: 0.4 },
                        data: chartData.map(d => d.temperature)
                    }
                ]
            });

            // 4. 音频特征图表
            if (bearing.audioFeatures && Object.keys(bearing.audioFeatures).length > 0) {
                charts[`audio-${displayId}`] = echarts.init(document.getElementById(`bearing-${displayId}-audio`));
                charts[`audio-${displayId}`].setOption({
                    title: { text: '音频特征', left: 'center' },
                    tooltip: { trigger: 'axis' },
                    legend: {
                        data: Object.keys(bearing.audioFeatures),
                        bottom: 0,
                        type: 'scroll'
                    },
                    grid: { top: '15%', bottom: '20%' },
                    xAxis: {
                        type: 'category',
                        data: timestamps,
                        axisLabel: { rotate: 45 }
                    },
                    yAxis: { type: 'value' },
                    series: Object.keys(bearing.audioFeatures).map(name => ({
                        name: name,
                        type: 'line',
                        showSymbol: false,
                        data: chartData.map(d => (d.audioFeatures || {})[name] || 0)
                    }))
                });
            }
        }

        // 更新音频特征显示
        function updateAudioFeatures(bearingId, features) {
            const container = document.getElementById(`bearing-${bearingId}-features`);
            if (!container || !features) return;

            container.innerHTML = '';
            Object.entries(features).forEach(([name, value]) => {
                const box = document.createElement('div');
                box.className = 'feature-box';
                box.innerHTML = `
                    <div class="feature-name">${name}</div>
                    <div class="feature-value">${typeof value === 'number' ? value.toFixed(4) : value}</div>
                `;
                container.appendChild(box);
            });
        }

        // 更新故障概率显示
        function updateProbability(bearingId, probability) {
            const percent = Math.round(probability * 100);
            const statusEl = document.getElementById(`bearing-${bearingId}-status`);
            const probEl = document.getElementById(`bearing-${bearingId}-probability`);
            const barEl = document.getElementById(`bearing-${bearingId}-probability-bar`);

            if (!statusEl || !probEl || !barEl) return;

            probEl.textContent = `${percent}%`;
            barEl.style.width = `${percent}%`;

            // 更新状态样式
            if (probability >= 0.7) {
                statusEl.textContent = '严重故障';
                statusEl.className = 'alert-status alert-danger';
                barEl.className = 'probability-fill danger';
            } else if (probability >= 0.4) {
                statusEl.textContent = '故障预警';
                statusEl.className = 'alert-status alert-warning';
                barEl.className = 'probability-fill warning';
            } else {
                statusEl.textContent = '正常';
                statusEl.className = 'alert-status alert-normal';
                barEl.className = 'probability-fill';
            }
        }

        // 页面加载完成后初始化
        document.addEventListener('DOMContentLoaded', () => {
            // 初始化所有轴承的图表
            backendData.bearings.forEach(bearing => {
                initBearingCharts(bearing);
                updateAudioFeatures(bearing.displayId, bearing.audioFeatures);
                updateProbability(bearing.displayId, bearing.probability);
            });

            // 窗口大小变化时重绘图表
            window.addEventListener('resize', () => {
                Object.values(charts).forEach(chart => {
                    chart && chart.resize();
                });
            });

            // 3秒自动刷新页面
            setInterval(() => {
                window.location.reload();
            }, 5000);
        });
    </script>
</body>
</html>